package server

import (
	codecs "sanguo/codec/cs"
	"sanguo/node/common/db"
	"sanguo/node/node_dir"
	cs_msg "sanguo/protocol/cs/message"
	"strconv"
	"time"

	"github.com/golang/protobuf/proto"

	"github.com/sniperHW/kendynet"
)

func getLastLogin(userId string) string {
	serverId, err := db.GetRedisClient("dir").HGet("last_login_map", userId).Result()
	if nil != err {
		if err.Error() == "redis: nil" {
			node_dir.Infoln(userId, "no lastLogin")
		} else {
			node_dir.Errorln("redis failed :", err)
		}

	}
	return serverId
}

func getLogged(userId string) map[string]string {
	key := "logged:" + userId
	loggedMap, err := db.GetRedisClient("dir").HGetAll(key).Result()
	if nil != err {
		node_dir.Errorln("getLogged :", err)
	}
	return loggedMap
}

func onGetServerList(session kendynet.StreamSession, msg *codecs.Message) {
	defer lockMap.Unlock()
	lockMap.Lock()

	var GetServerListTime int64
	if GetServerListTime == 0 {
		GetServerListTime = time.Now().UnixNano() / 1e6
	}

	seqNo := msg.GetSeriNo()
	serverListToS := msg.GetData().(*cs_msg.ServerListToS)
	userId := serverListToS.GetUserID()

	lastLogin := getLastLogin(userId)
	loggedMap := getLogged(userId)

	serverListToC := &cs_msg.ServerListToC{}
	for _, v := range serverMap {
		server := &cs_msg.Server{}

		if v.ServerStatus == 1 {
			server.ServerType = cs_msg.ServerType(cs_msg.ServerType_OPERATION).Enum()
		} else {
			server.ServerType = cs_msg.ServerType(cs_msg.ServerType_SHUTOFF).Enum()
		}
		server.UserType = cs_msg.UserType(cs_msg.UserType_NO_LOGIN).Enum()
		server.ServerId = proto.Int32(v.ServerId)
		server.ServerName = proto.String(v.ServerName)
		server.ServerAddr = proto.String(v.ServerAddr)
		server.PlayerNum = proto.Int32(v.playerNum)
		server.PLevel = proto.Int32(0)

		serverListToC.ServerList = append(serverListToC.ServerList, server)

	}

	// 最后登录id
	var lastLoginId int = 0
	if lastLogin != "" {
		lastLoginId, _ = strconv.Atoi(lastLogin)
	}

	for _, v := range serverListToC.ServerList {
		if int(v.GetServerId()) == lastLoginId {
			v1, _ := loggedMap[strconv.FormatInt(int64(v.GetServerId()), 10)]
			pLevel, _ := strconv.Atoi(v1)
			v.UserType = cs_msg.UserType(cs_msg.UserType_LAST_LOGIN).Enum()
			v.PLevel = proto.Int32(int32(pLevel))
			delete(loggedMap, strconv.FormatInt(int64(v.GetServerId()), 10))
		} else if v1, ok := loggedMap[strconv.FormatInt(int64(v.GetServerId()), 10)]; ok {
			pLevel, _ := strconv.Atoi(v1)
			v.UserType = cs_msg.UserType(cs_msg.UserType_LOGGED).Enum()
			v.PLevel = proto.Int32(int32(pLevel))
			delete(loggedMap, strconv.FormatInt(int64(v.GetServerId()), 10))
		}
	}

	if GetServerListTime != 0 {
		useTime := time.Now().UnixNano()/1e6 - GetServerListTime
		if useTime > 100 {
			node_dir.Debugln("GetServerListTime ---------->", useTime)
		}
		GetServerListTime = 0
	}

	node_dir.Infoln("onGetServerList:", serverListToC)
	session.Send(codecs.NewMessage(seqNo, serverListToC))
	session.Close(" Close", 1)

}

func init() {
	node_dir.RegisterHandler(&cs_msg.ServerListToS{}, onGetServerList)
}
